external initialize: unit -> unit = "caml_Pm_Initialize"
external terminate: unit -> unit = "caml_Pm_Terminate"

type device_id = int
type device_info = {
	interf: string;
	name: string;
	input: bool;
	output: bool;
}
external count_devices: unit -> int = "caml_Pm_CountDevices"
external get_default_input_device_id: unit -> device_id = "caml_Pm_GetDefaultInputDeviceID"
external get_default_output_device_id: unit -> device_id = "caml_Pm_GetDefaultOutputDeviceID"
external get_device_info: device_id -> device_info = "caml_Pm_GetDeviceInfo"

type stream
type timestamp = int
external open_input_simple: device_id -> int -> stream = "caml_Pm_OpenInput_Simple"
external open_input: device_id -> int -> ('a -> int) -> 'a -> stream = "caml_Pm_OpenInput"
external open_output_simple: device_id -> int -> int -> stream = "caml_Pm_OpenOutput_Simple"
external open_output: device_id -> int -> ('a -> int) -> 'a -> int -> stream = "caml_Pm_OpenOutput"
external has_host_error: stream -> bool = "caml_Pm_HasHostError"
external abort: stream -> unit = "caml_Pm_Abort"
external close: stream -> unit = "caml_Pm_Close"

val filt_active: int
val filt_sysex: int
val filt_clock: int
external set_filter: stream -> int -> unit = "caml_Pm_SetFilter"

type message = string
val message: int -> int -> int -> message
val message_status: message -> int
val message_data1:  message -> int
val message_data2: message -> int

type event = { message: message; timestamp: timestamp }
external read: stream -> int -> event list = "caml_Pm_Read"
external poll: stream -> bool = "caml_Pm_Poll"
external write: stream -> event list -> unit = "caml_Pm_Write"
external write_short: stream -> timestamp -> message -> unit = "caml_Pm_WriteShort"
external write_sysex: stream -> timestamp -> string -> unit = "caml_Pm_WriteSysEx"
